#ifndef __RS485_Wind_Direction_Transmitter_V2_H__
#define __RS485_Wind_Direction_Transmitter_V2_H__

#include "Arduino.h"
#include <SoftwareSerial.h>


class RS485_Wind_Direction_Transmitter_V2
{
public:
  RS485_Wind_Direction_Transmitter_V2();
  ~RS485_Wind_Direction_Transmitter_V2();

  void begin(HardwareSerial &myhardSerial);
  void begin(SoftwareSerial &mysoftSerial);

  /**
       @brief 读取风向方位（16方位）

       @param Address Modbus从机地址
       @return 风向方位（0-16）
      Return the value to the direction correspondence table
      -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      |   value   |   0   |     1     |     2     |     3     |  4   |     5     |     6     |     7     |   8   |     9     |     10    |     11    |  12  |    13     |     14    |     15    |     16    |
      |-----------|-------|-----------|-----------|-----------|------|-----------|-----------|-----------|-------|-----------|-----------|-----------|------|-----------|-----------|-----------|-----------|
      | Direction | North | Northeast | Northeast | Northeast | East | Southeast | Southeast | Southeast | South | Southwest | Southwest | Southwest | West | Northwest | Northwest | Northwest |    North  |
      |           |       | by north  |           |  by east  |      |  by east  |           | by south  |       | by south  |           |  by west  |      |  by west  |           | by north  |           |
      -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    */
  
  uint8_t GetWindDirection(uint8_t Address);
  /**
       @brief 读取风向角度（360度）

       @param Adderss Modbus从机地址
       @return float 风向角度（0-360度）
    */
  float GetWindAngle(uint8_t Adderss);

  /**
     @brief 修改风向传感器Modbus从机地址，立即生效

      @param Address1 当前Modbus从机地址，（0x00为广播地址可以修改任意地址的传感器）
      @param Address2 想要修改的地址
      @return true 修改成功
      @return false 修改失败
  */
  bool SetSlaveAddress(uint8_t Address1, uint8_t Address2);

  /**
    @brief 读取风向传感器的Modbus从机地址

    @return Modbus从机地址（0-255）
  */
  uint8_t GetSlaveAddress();

private:

  uint8_t serialMode;
  
  SoftwareSerial *_softSerial;
  HardwareSerial *_hardSerial;

  size_t readN(uint8_t *buf, size_t len);

  /**
       @brief 计算CRC16_2检验值

       @param buf 需要计算校验值的数据包
       @param len 需要校验的数据长度。
       @return uint16_t 返回一个16位的校验结果。
    */
  uint16_t CRC16_2(uint8_t *buf, int16_t len);

  /**
       @brief 为数据包末尾添加CRC_16校验

       @param buf 需要添加校验值的数据包
       @param len 需要添加校验的数据长度。
    */
  void addedCRC(uint8_t *buf, int len);

  /**
       @brief 读取单个Modbus寄存器

       @param Address Modbus从机地址
       @param reg 寄存器地址
       @param data 存储要读取的数据，一个寄存器储存2*uint8_t的数据
       @return true 读取成功
       @return false 读取失败
    */
  bool readHoldingRegister(uint8_t Address, uint16_t reg, uint8_t *data);

  /**
     @brief 写单个Modbus寄存器

      @param Address Modbus从机地址
      @param reg 寄存器地址
      @param parameter 需要写入的数据
      @return true 写入成功
      @return false 写入失败
  */
  bool writeHoldingRegister(uint8_t Address, uint16_t reg, uint16_t parameter);



};





#endif